package com.fm.base.json;

import com.fm.base.util.Pair;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.Iterator;
import java.util.Map;

public class JsonUtil {
	@SuppressWarnings("unchecked")
	public static String toJson(Object json) {
		if (json instanceof Map) {
			StringBuilder buf = new StringBuilder("{");
			Iterator<Map.Entry<Object, Object>> iterator = ((Map<Object, Object>) json).entrySet().iterator();
			while (iterator.hasNext()) {
				Map.Entry<Object, Object> entry = iterator.next();
				buf.append('"').append(entry.getKey()).append("\" : ").append(toJson(entry.getValue()));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("}");
			return buf.toString();
		} else if (json instanceof Iterable) {
			StringBuilder buf = new StringBuilder("[");
			Iterator<Object> iterator = ((Iterable) json).iterator();
			while (iterator.hasNext()) {
				buf.append(toJson(iterator.next()));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("]");
			return buf.toString();
		} else if (json != null && json.getClass().isArray()) {
			StringBuilder buf = new StringBuilder("[");
			Object[] array = (Object[]) json;
			for (int index = 0; index < array.length; ++index) {
				buf.append(toJson(array[index]));
				if (index < array.length - 1) {
					buf.append(",");
				}
			}
			buf.append("]");
			return buf.toString();
		} else if (json instanceof String || json instanceof Character) {
			return '"' + json.toString() + '"';
		} else {
			return String.valueOf(json);
		}
	}

	@SuppressWarnings("unchecked")
	public static String toLiteJson(Object json) {
		if (json instanceof Map) {
			StringBuilder buf = new StringBuilder("{");
			Iterator<Map.Entry<Object, Object>> iterator = ((Map<Object, Object>) json).entrySet().iterator();
			while (iterator.hasNext()) {
				Map.Entry<Object, Object> entry = iterator.next();
				buf.append('"').append(entry.getKey()).append("\":").append(toLiteJson(entry.getValue()));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("}");
			return buf.toString();
		} else if (json instanceof Iterable) {
			StringBuilder buf = new StringBuilder("[");
			Iterator<Object> iterator = ((Iterable) json).iterator();
			while (iterator.hasNext()) {
				buf.append(toLiteJson(iterator.next()));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("]");
			return buf.toString();
		} else if (json != null && json.getClass().isArray()) {
			StringBuilder buf = new StringBuilder("[");
			Object[] array = (Object[]) json;
			for (int index = 0; index < array.length; ++index) {
				buf.append(toLiteJson(array[index]));
				if (index < array.length - 1) {
					buf.append(",");
				}
			}
			buf.append("]");
			return buf.toString();
		} else if (json instanceof String || json instanceof Character) {
			return '"' + StringEscapeUtils.escapeJson(json.toString()) + '"';
		} else {
			return String.valueOf(json);
		}
	}

	public static String toFormatJson(Object object) {
		return toFormatJson(object, 0);
	}

	@SuppressWarnings("unchecked")
	private static String toFormatJson(Object object, int deepth) {
		if (object instanceof Map) {
			StringBuilder buf = new StringBuilder("{");
			Iterator<Map.Entry<Object, Object>> iterator = ((Map<Object, Object>) object).entrySet().iterator();
			while (iterator.hasNext()) {
				Map.Entry<Object, Object> entry = iterator.next();
				buf.append("\n");
				for (int i = 0; i <= deepth; ++i) {
					buf.append("\t");
				}
				buf.append("\"").append(entry.getKey()).append("\" : ").append(toFormatJson(entry.getValue(), deepth + 1));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("\n");
			for (int i = 0; i < deepth; ++i) {
				buf.append("\t");
			}
			buf.append("}");
			return buf.toString();
		} else if (object instanceof Iterable) {
			StringBuilder buf = new StringBuilder("[");
			Iterator<Object> iterator = ((Iterable) object).iterator();
			while (iterator.hasNext()) {
				buf.append("\n");
				for (int i = 0; i <= deepth; ++i) {
					buf.append("\t");
				}
				buf.append(toFormatJson(iterator.next(), deepth + 1));
				if (iterator.hasNext()) {
					buf.append(",");
				}
			}
			buf.append("\n");
			for (int i = 0; i < deepth; ++i) {
				buf.append("\t");
			}
			buf.append("]");
			return buf.toString();
		} else if (object != null && object.getClass().isArray()) {
			StringBuilder buf = new StringBuilder("[");
			Object[] array = (Object[]) object;
			for (int index = 0; index < array.length; ++index) {
				buf.append("\n");
				for (int i = 0; i <= deepth; ++i) {
					buf.append("\t");
				}
				buf.append(toFormatJson(array[index], deepth + 1));
				if (index < array.length - 1) {
					buf.append(",");
				}
			}
			buf.append("\n");
			for (int i = 0; i < deepth; ++i) {
				buf.append("\t");
			}
			buf.append("]");
			return buf.toString();
		} else if (object instanceof JsonString || object instanceof String || object instanceof Character) {
			return '"' + object.toString() + '"';
		} else {
			return String.valueOf(object);
		}
	}
}
